Change machinery for following font rendering xsettings to set cairo font
authorOwen Taylor <otaylor@redhat.com>
Thu, 21 Jul 2005 13:59:22 +0000 (13:59 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 21 Jul 2005 13:59:22 +0000 (13:59 +0000)
2005-07-19  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtksettings.c gtk/gtkwidget.c: Change machinery for
        following font rendering xsettings to set cairo font
        options on PangoContext

        * gdk/x11/gdkxftdefaults.c gdk/x11/gdkevents-x11.c gdkscreen-x11.h
        gdkprivate-x11.h: Get default values for rendering options
        (such as antialiasing, dpi) from the Xft resources for the
        display, borrowing a bit of code from Xft.

        * gtk/gtksettings.c (gtk_settings_class_init): Fix docs for
        values of gtk-xft-hintstyle.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-8
gdk/x11/Makefile.am
gdk/x11/gdkevents-x11.c
gdk/x11/gdkprivate-x11.h
gdk/x11/gdkscreen-x11.h
gdk/x11/gdkxftdefaults.c [new file with mode: 0644]
gtk/gtksettings.c
gtk/gtkwidget.c

index 1c2a3cf3d5aa0007f5cd5848072d837498ee59f5..6dc48961aeaed6384fc19f0f70fcd7a94f3bb956 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-07-19  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c gtk/gtkwidget.c: Change machinery for
+       following font rendering xsettings to set cairo font
+       options on PangoContext
+
+       * gdk/x11/gdkxftdefaults.c gdk/x11/gdkevents-x11.c gdkscreen-x11.h
+       gdkprivate-x11.h: Get default values for rendering options
+       (such as antialiasing, dpi) from the Xft resources for the
+       display, borrowing a bit of code from Xft.
+
+       * gtk/gtksettings.c (gtk_settings_class_init): Fix docs for
+       values of gtk-xft-hintstyle.
+
 2005-07-21  Tor Lillqvist  <tml@novell.com>
 
        * gtk/gtk.symbols: Make GtkPlug/Socket API available with all
index 1c2a3cf3d5aa0007f5cd5848072d837498ee59f5..6dc48961aeaed6384fc19f0f70fcd7a94f3bb956 100644 (file)
@@ -1,3 +1,17 @@
+2005-07-19  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c gtk/gtkwidget.c: Change machinery for
+       following font rendering xsettings to set cairo font
+       options on PangoContext
+
+       * gdk/x11/gdkxftdefaults.c gdk/x11/gdkevents-x11.c gdkscreen-x11.h
+       gdkprivate-x11.h: Get default values for rendering options
+       (such as antialiasing, dpi) from the Xft resources for the
+       display, borrowing a bit of code from Xft.
+
+       * gtk/gtksettings.c (gtk_settings_class_init): Fix docs for
+       values of gtk-xft-hintstyle.
+
 2005-07-21  Tor Lillqvist  <tml@novell.com>
 
        * gtk/gtk.symbols: Make GtkPlug/Socket API available with all
index 1c2a3cf3d5aa0007f5cd5848072d837498ee59f5..6dc48961aeaed6384fc19f0f70fcd7a94f3bb956 100644 (file)
@@ -1,3 +1,17 @@
+2005-07-19  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c gtk/gtkwidget.c: Change machinery for
+       following font rendering xsettings to set cairo font
+       options on PangoContext
+
+       * gdk/x11/gdkxftdefaults.c gdk/x11/gdkevents-x11.c gdkscreen-x11.h
+       gdkprivate-x11.h: Get default values for rendering options
+       (such as antialiasing, dpi) from the Xft resources for the
+       display, borrowing a bit of code from Xft.
+
+       * gtk/gtksettings.c (gtk_settings_class_init): Fix docs for
+       values of gtk-xft-hintstyle.
+
 2005-07-21  Tor Lillqvist  <tml@novell.com>
 
        * gtk/gtk.symbols: Make GtkPlug/Socket API available with all
index 13a05aaf5af54339987ac2e2787bd62a9490a993..d6168df23ae87d130b779b093796724f795ab957 100644 (file)
@@ -49,6 +49,7 @@ libgdk_x11_la_SOURCES =       \
        gdkvisual-x11.c         \
        gdkwindow-x11.c         \
        gdkwindow-x11.h         \
+       gdkxftdefaults.c        \
        gdkxid.c                \
        gdkx.h                  \
        gdkprivate-x11.h        \
index 74e99913562710c124f9f9b62ded517b9de7cf06..afbfedb9769144b90cf36a762d7d89c98ffabb4b 100644 (file)
@@ -2895,7 +2895,7 @@ gdk_screen_get_setting (GdkScreen   *screen,
 
   const char *xsettings_name = NULL;
   XSettingsResult result;
-  XSettingsSetting *setting;
+  XSettingsSetting *setting = NULL;
   GdkScreenX11 *screen_x11;
   gboolean success = FALSE;
   gint i;
@@ -2913,12 +2913,12 @@ gdk_screen_get_setting (GdkScreen   *screen,
       }
 
   if (!xsettings_name)
-    return FALSE;
+    goto out;
 
   result = xsettings_client_get_setting (screen_x11->xsettings_client, 
                                         xsettings_name, &setting);
   if (result != XSETTINGS_SUCCESS)
-    return FALSE;
+    goto out;
 
   switch (setting->type)
     {
@@ -2965,9 +2965,14 @@ gdk_screen_get_setting (GdkScreen   *screen,
   
   g_value_unset (&tmp_val);
 
-  xsettings_setting_free (setting);
+ out:
+  if (setting)
+    xsettings_setting_free (setting);
 
-  return success;
+  if (success)
+    return TRUE;
+  else
+    return _gdk_x11_get_xft_setting (screen, name, value);
 }
 
 static GdkFilterReturn 
index 4da0d0caa02c77e4be144f94ac46b7ef68fc9f30..5e9e2cba617be8c5068609af26b1d0be1a971cad 100644 (file)
@@ -176,6 +176,10 @@ PangoRenderer *_gdk_x11_renderer_get (GdkDrawable *drawable,
 
 void _gdk_x11_cursor_update_theme (GdkCursor *cursor);
 
+gboolean _gdk_x11_get_xft_setting (GdkScreen   *screen,
+                                  const gchar *name,
+                                  GValue      *value);
+
 extern GdkDrawableClass  _gdk_x11_drawable_class;
 extern gboolean                 _gdk_use_xshm;
 extern const int         _gdk_nenvent_masks;
index aa08dca15ba47de8096984ccd4b01a0b54ff57c2..5ea82a4fbccd0e252aeffbedafab65c182b8e317 100644 (file)
@@ -93,6 +93,16 @@ struct _GdkScreenX11
 
   /* Pango renderer object singleton */
   PangoRenderer *renderer;
+
+  /* Xft resources for the display, used for default values for
+   * the Xft/ XSETTINGS
+   */
+  gboolean xft_init;           /* Whether we've intialized these values yet */
+  gboolean xft_antialias;
+  gboolean xft_hinting;
+  gint xft_hintstyle;
+  gint xft_rgba;
+  gint xft_dpi;
 };
   
 struct _GdkScreenX11Class
diff --git a/gdk/x11/gdkxftdefaults.c b/gdk/x11/gdkxftdefaults.c
new file mode 100644 (file)
index 0000000..47248e0
--- /dev/null
@@ -0,0 +1,294 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright © 2005 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Based on code from xftdpy.c
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <fontconfig/fontconfig.h>
+
+#include <gdkscreen-x11.h>
+#include <gdkx.h>
+
+static gint
+parse_boolean (char *v)
+{
+  gchar c0, c1;
+  
+  c0 = *v;
+  if (g_ascii_isupper ((int)c0))
+    c0 = g_ascii_tolower (c0);
+  if (c0 == 't' || c0 == 'y' || c0 == '1')
+    return 1;
+  if (c0 == 'f' || c0 == 'n' || c0 == '0')
+    return 0;
+  if (c0 == 'o')
+    {
+      c1 = v[1];
+      if (g_ascii_isupper ((int)c1))
+       c1 = g_ascii_tolower (c1);
+      if (c1 == 'n')
+       return 1;
+      if (c1 == 'f')
+       return 0;
+    }
+  
+  return -1;
+}
+
+static gboolean
+get_boolean_default (Display *dpy,
+                    gchar   *option,
+                    gboolean *value)
+{
+  gchar *v;
+  gint i;
+  
+  v = XGetDefault (dpy, "Xft", option);
+  if (v)
+    {
+      i = parse_boolean (v);
+      if (i >= 0)
+       {
+         *value = i;
+         return TRUE;
+       }
+    }
+  
+  return FALSE;
+}
+
+static gboolean
+get_double_default (Display *dpy,
+                   gchar   *option,
+                   gdouble *value)
+{
+  gchar    *v, *e;
+  
+  v = XGetDefault (dpy, "Xft", option);
+  if (v)
+    {
+      /* Xft uses strtod, though localization probably wasn't
+       * desired. For compatibility, we use the conservative
+       * g_strtod() that accepts either localized or non-localized
+       * decimal separator.
+       */
+      *value = g_strtod (v, &e);
+      if (e != v)
+       return TRUE;
+    }
+  
+  return FALSE;
+}
+
+static gboolean
+get_integer_default (Display *dpy,
+                    gchar   *option,
+                    gint    *value)
+{
+  gint i;
+  gchar *v, *e;
+  
+  v = XGetDefault (dpy, "Xft", option);
+  if (v)
+    {
+      if (FcNameConstant ((FcChar8 *) v, value))
+       return TRUE;
+      
+      i = strtol (v, &e, 0);
+      if (e != v)
+       return TRUE;
+    }
+  
+  return FALSE;
+}
+
+static void
+init_xft_settings (GdkScreen *screen)
+{
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+  Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
+  int xscreen = GDK_SCREEN_XNUMBER (screen);
+  double dpi_double;
+
+  if (screen_x11->xft_init)
+    return;
+
+  screen_x11->xft_init = TRUE;
+
+  if (!get_boolean_default (xdisplay, "antialias", &screen_x11->xft_antialias))
+    screen_x11->xft_antialias = TRUE;
+
+  if (!get_boolean_default (xdisplay, "hinting", &screen_x11->xft_hinting))
+    screen_x11->xft_hinting = TRUE;
+
+  if (!get_integer_default (xdisplay, "hintstyle", &screen_x11->xft_hintstyle))
+    screen_x11->xft_hintstyle = FC_HINT_FULL;
+
+  if (!get_integer_default (xdisplay, "rgba", &screen_x11->xft_rgba))
+                           
+    {
+      int subpixel = FC_RGBA_UNKNOWN;
+      
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
+      if (_gdk_x11_have_render (screen_x11->display))
+       {
+         int render_order = XRenderQuerySubpixelOrder (xdisplay, xscreen);
+         
+         switch (render_order)
+           {
+           default:
+           case SubPixelUnknown:
+             subpixel = FC_RGBA_UNKNOWN;
+             break;
+           case SubPixelHorizontalRGB:
+             subpixel = FC_RGBA_RGB;
+             break;
+           case SubPixelHorizontalBGR:
+             subpixel = FC_RGBA_BGR;
+             break;
+           case SubPixelVerticalRGB:
+             subpixel = FC_RGBA_VRGB;
+             break;
+           case SubPixelVerticalBGR:
+             subpixel = FC_RGBA_VBGR;
+             break;
+           case SubPixelNone:
+             subpixel = FC_RGBA_NONE;
+             break;
+           }
+       }
+
+      screen_x11->xft_rgba = subpixel;
+#endif
+    }
+
+  if (!get_double_default (xdisplay, "dpi", &dpi_double))
+    dpi_double = (((double) DisplayHeight (xdisplay, xscreen) * 25.4) / 
+                 (double) DisplayHeightMM (xdisplay, xscreen));
+
+  screen_x11->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
+}
+
+gboolean
+_gdk_x11_get_xft_setting (GdkScreen   *screen,
+                         const gchar *name,
+                         GValue      *value)
+{
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+  
+  if (strncmp (name, "gtk-xft-", 8) != 0)
+    return FALSE;
+
+  name += 8;
+
+  init_xft_settings (screen);
+
+  if (strcmp (name, "antialias") == 0)
+    {
+      g_value_set_int (value, screen_x11->xft_antialias);
+      return TRUE;
+    }
+  else if (strcmp (name, "hinting") == 0)
+    {
+      g_value_set_int (value, screen_x11->xft_hinting);
+      return TRUE;
+    }
+  else if (strcmp (name, "hintstyle") == 0)
+    {
+      const char *str;
+      
+      switch (screen_x11->xft_hintstyle)
+       {
+       case FC_HINT_NONE:
+         str = "hintnone";
+         break;
+       case FC_HINT_SLIGHT:
+         str = "hintslight";
+         break;
+       case FC_HINT_MEDIUM:
+         str = "hintmedium";
+         break;
+       case FC_HINT_FULL:
+         str = "hintfull";
+         break;
+       default:
+         return FALSE;
+       }
+
+      g_value_set_string (value, str);
+      return TRUE;
+    }
+  else if (strcmp (name, "rgba") == 0)
+    {
+      const char *str;
+      
+      switch (screen_x11->xft_rgba)
+       {
+       case FC_RGBA_NONE:
+         str = "none";
+         break;
+       case FC_RGBA_RGB:
+         str = "rgb";
+         break;
+       case FC_RGBA_BGR:
+         str = "bgr";
+         break;
+       case FC_RGBA_VRGB:
+         str = "vrgb";
+         break;
+       case FC_RGBA_VBGR:
+         str = "vbgr";
+         break;
+       case FC_RGBA_UNKNOWN:
+       default:
+         return FALSE;
+       }
+       
+      g_value_set_string (value, str);
+      return TRUE; 
+   }
+  else if (strcmp (name, "dpi") == 0)
+    {
+      g_value_set_int (value, screen_x11->xft_dpi);
+      return TRUE;
+    }
+
+  return FALSE;
+}
index 0f9aa9cdb21621e44d57ba7c694621a3c8d67c80..b05e6f4311cd8b970c43bbc1a6a4a7c50662a431 100644 (file)
@@ -143,88 +143,6 @@ gtk_settings_get_type (void)
   return settings_type;
 }
 
-#if 0
-static void
-       
-gtk_default_substitute (FcPattern *pattern,
-                       gpointer   data)
-{
-  GtkSettings *settings = data;
-  gint antialias;
-  gint hinting;
-  char *rgba;
-  char *hintstyle;
-  gint dpi;
-  FcValue v;
-  
-  g_object_get (settings,
-               "gtk-xft-antialias", &antialias,
-               "gtk-xft-hinting", &hinting,
-               "gtk-xft-hintstyle", &hintstyle,
-               "gtk-xft-rgba", &rgba,
-               "gtk-xft-dpi", &dpi,
-               NULL);
-  
-  if (antialias >= 0 &&
-      FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
-    FcPatternAddBool (pattern, FC_ANTIALIAS, antialias != 0);
-  
-  if (hinting >= 0 &&
-      FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
-    FcPatternAddBool (pattern, FC_HINTING, hinting != 0);
-#ifdef FC_HINT_STYLE 
-  if (hintstyle && FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
-    {
-      int val = FC_HINT_FULL;  /* Quiet GCC */
-      gboolean found = TRUE;
-
-      if (strcmp (hintstyle, "hintnone") == 0)
-       val = FC_HINT_NONE;
-      else if (strcmp (hintstyle, "hintslight") == 0)
-       val = FC_HINT_SLIGHT;
-      else if (strcmp (hintstyle, "hintmedium") == 0)
-       val = FC_HINT_MEDIUM;
-      else if (strcmp (hintstyle, "hintfull") == 0)
-       val = FC_HINT_FULL;
-      else
-       found = FALSE;
-
-      if (found)
-       FcPatternAddInteger (pattern, FC_HINT_STYLE, val);
-    }
-#endif /* FC_HINT_STYLE */
-
-  if (rgba && FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
-    {
-      int val = FC_RGBA_NONE;  /* Quiet GCC */
-      gboolean found = TRUE;
-
-      if (strcmp (rgba, "none") == 0)
-       val = FC_RGBA_NONE;
-      else if (strcmp (rgba, "rgb") == 0)
-       val = FC_RGBA_RGB;
-      else if (strcmp (rgba, "bgr") == 0)
-       val = FC_RGBA_BGR;
-      else if (strcmp (rgba, "vrgb") == 0)
-       val = FC_RGBA_VRGB;
-      else if (strcmp (rgba, "vbgr") == 0)
-       val = FC_RGBA_VBGR;
-      else
-       found = FALSE;
-
-      if (found)
-       FcPatternAddInteger (pattern, FC_RGBA, val);
-    }
-
-  if (dpi >= 0 && FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
-    FcPatternAddDouble (pattern, FC_DPI, dpi / 1024.);
-
-  g_free (hintstyle);
-  g_free (rgba);
-}
-#endif /* GDK_WINDOWING_X11 */
-
 static void
 gtk_settings_init (GtkSettings *settings)
 {
@@ -411,7 +329,7 @@ gtk_settings_class_init (GtkSettingsClass *class)
   result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-xft-hintstyle",
                                                                  P_("Xft Hint Style"),
-                                                                 P_("What degree of hinting to use; none, slight, medium, or full"),
+                                                                 P_("What degree of hinting to use; hintnone, hintslight, hintmedium, or hintfull"),
                                                                  NULL,
                                                                  GTK_PARAM_READWRITE),
                                               NULL);
@@ -509,15 +427,6 @@ gtk_settings_get_for_screen (GdkScreen *screen)
       settings->screen = screen;
       g_object_set_data (G_OBJECT (screen), "gtk-settings", settings);
 
-#if 0
-      /* Set the default substitution function for the Pango fontmap.
-       */
-      pango_xft_set_default_substitute (GDK_SCREEN_XDISPLAY (screen),
-                                       GDK_SCREEN_XNUMBER (screen),
-                                       gtk_default_substitute,
-                                       settings, NULL);
-#endif /* GDK_WINDOWING_X11 */
-      
       gtk_rc_reparse_all_for_settings (settings, TRUE);
       settings_update_double_click (settings);
     }
@@ -646,22 +555,18 @@ gtk_settings_notify (GObject    *object,
     case PROP_DOUBLE_CLICK_DISTANCE:
       settings_update_double_click (settings);
       break;
-#if 0
+#ifdef GDK_WINDOWING_X11
+    case PROP_XFT_DPI:
     case PROP_XFT_ANTIALIAS:
     case PROP_XFT_HINTING:
     case PROP_XFT_HINTSTYLE:
     case PROP_XFT_RGBA:
-    case PROP_XFT_DPI:
-      pango_xft_substitute_changed (GDK_SCREEN_XDISPLAY (settings->screen),
-                                   GDK_SCREEN_XNUMBER (settings->screen));
       /* This is a hack because with gtk_rc_reset_styles() doesn't get
        * widgets with gtk_widget_style_set(), and also causes more
        * recomputation than necessary.
        */
       gtk_rc_reset_styles (GTK_SETTINGS (object));
       break;
-#endif
-#ifdef GDK_WINDOWING_X11
     case PROP_CURSOR_THEME_NAME:
     case PROP_CURSOR_THEME_SIZE:
       settings_update_cursor_theme (settings);
index be14943426775f858e2dc614db79634a958dc798..60f588fc27b2f6231474b0d3eca47e75d8d2d7e6 100644 (file)
@@ -204,6 +204,7 @@ static gboolean             gtk_widget_real_focus_out_event         (GtkWidget        *widget,
 static gboolean                gtk_widget_real_focus                   (GtkWidget        *widget,
                                                                 GtkDirectionType  direction);
 static PangoContext*   gtk_widget_peek_pango_context           (GtkWidget        *widget);
+static void            gtk_widget_update_pango_context         (GtkWidget        *widget);
 static void            gtk_widget_propagate_state              (GtkWidget        *widget,
                                                                 GtkStateData     *data);
 static void             gtk_widget_reset_rc_style               (GtkWidget        *widget);
@@ -4932,13 +4933,6 @@ gtk_widget_set_style_internal (GtkWidget *widget,
   g_object_ref (widget);
   g_object_freeze_notify (G_OBJECT (widget));
 
-  if (widget->style != style || initial_emission)
-    {
-      PangoContext *context = gtk_widget_peek_pango_context (widget);
-      if (context)
-       pango_context_set_font_description (context, style->font_desc);
-    }
-  
   if (widget->style != style)
     {
       GtkStyle *previous_style;
@@ -4956,6 +4950,7 @@ gtk_widget_set_style_internal (GtkWidget *widget,
       if (GTK_WIDGET_REALIZED (widget))
        widget->style = gtk_style_attach (widget->style, widget->window);
 
+      gtk_widget_update_pango_context (widget);
       g_signal_emit (widget,
                     widget_signals[STYLE_SET],
                     0,
@@ -4966,10 +4961,13 @@ gtk_widget_set_style_internal (GtkWidget *widget,
        gtk_widget_queue_resize (widget);
     }
   else if (initial_emission)
-    g_signal_emit (widget,
-                  widget_signals[STYLE_SET],
-                  0,
-                  NULL);
+    {
+      gtk_widget_update_pango_context (widget);
+      g_signal_emit (widget,
+                    widget_signals[STYLE_SET],
+                    0,
+                    NULL);
+    }
   g_object_notify (G_OBJECT (widget), "style");
   g_object_thaw_notify (G_OBJECT (widget));
   g_object_unref (widget);
@@ -5195,6 +5193,101 @@ gtk_widget_get_pango_context (GtkWidget *widget)
   return context;
 }
 
+static void
+update_pango_context (GtkWidget    *widget,
+                     PangoContext *context)
+{
+#ifdef GDK_WINDOWING_X11
+  GtkSettings *settings;
+  gint hinting;
+  char *hint_style_str;
+  cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_DEFAULT;
+  gint antialias;
+  cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_DEFAULT;
+  char *rgba_str;
+  cairo_subpixel_order_t subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
+  int dpi;
+  cairo_font_options_t *options;
+#endif
+      
+  pango_context_set_font_description (context, widget->style->font_desc);
+  pango_context_set_base_dir (context,
+                             gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
+                             PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
+  
+#ifdef GDK_WINDOWING_X11
+  settings = gtk_widget_get_settings (widget);
+  g_object_get (settings,
+               "gtk-xft-antialias", &antialias,
+               "gtk-xft-hinting", &hinting,
+               "gtk-xft-hintstyle", &hint_style_str,
+               "gtk-xft-rgba", &rgba_str,
+               "gtk-xft-dpi", &dpi,
+               NULL);
+
+  if (dpi > 0)
+    pango_cairo_context_set_resolution (context, dpi / 1024.);
+  else
+    pango_cairo_context_set_resolution (context, -1.);
+
+  options = cairo_font_options_create ();
+  
+  if (hinting >= 0 && !hinting)
+    {
+      hint_style = CAIRO_HINT_STYLE_NONE;
+    }
+  else if (hint_style_str)
+    {
+      if (strcmp (hint_style_str, "hintnone") == 0)
+       hint_style = CAIRO_HINT_STYLE_NONE;
+      else if (strcmp (hint_style_str, "hintslight") == 0)
+       hint_style = CAIRO_HINT_STYLE_SLIGHT;
+      else if (strcmp (hint_style_str, "hintmedium") == 0)
+       hint_style = CAIRO_HINT_STYLE_MEDIUM;
+      else if (strcmp (hint_style_str, "hintfull") == 0)
+       hint_style = CAIRO_HINT_STYLE_FULL;
+    }
+
+  cairo_font_options_set_hint_style (options, hint_style);
+
+  if (rgba_str)
+    {
+      if (strcmp (rgba_str, "rgb") == 0)
+       subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
+      else if (strcmp (rgba_str, "bgr") == 0)
+       subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
+      else if (strcmp (rgba_str, "vrgb") == 0)
+       subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
+      else if (strcmp (rgba_str, "vbgr") == 0)
+       subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
+    }
+
+  cairo_font_options_set_subpixel_order (options, subpixel_order);
+  
+  if (antialias >= 0 && !antialias)
+    antialias_mode = CAIRO_ANTIALIAS_NONE;
+  else if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
+    antialias_mode = CAIRO_ANTIALIAS_SUBPIXEL;
+  else if (antialias >= 0)
+    antialias_mode = CAIRO_ANTIALIAS_GRAY;
+  
+  cairo_font_options_set_antialias (options, antialias_mode);
+
+  pango_cairo_context_set_font_options (context, options);
+  
+  cairo_font_options_destroy (options);
+#endif  
+}
+
+static void
+gtk_widget_update_pango_context (GtkWidget *widget)
+{
+  PangoContext *context = gtk_widget_peek_pango_context (widget);
+  
+  if (context)
+    update_pango_context (widget, context);
+}
+
 /**
  * gtk_widget_create_pango_context:
  * @widget: a #GtkWidget
@@ -5224,10 +5317,7 @@ gtk_widget_create_pango_context (GtkWidget *widget)
 
   context = gdk_pango_context_get_for_screen (screen);
 
-  pango_context_set_base_dir (context,
-                             gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
-                               PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
-  pango_context_set_font_description (context, widget->style->font_desc);
+  update_pango_context (widget, context);
   pango_context_set_language (context, gtk_get_default_language ());
 
   return context;
@@ -6476,12 +6566,7 @@ static void
 gtk_widget_emit_direction_changed (GtkWidget        *widget,
                                   GtkTextDirection  old_dir)
 {
-  PangoContext *context = gtk_widget_peek_pango_context (widget);
-
-  if (context)
-    pango_context_set_base_dir (context,
-                               gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
-                                 PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL);
+  gtk_widget_update_pango_context (widget);
   
   g_signal_emit (widget, widget_signals[DIRECTION_CHANGED], 0, old_dir);
 }